package com.gitee.wsl.compose.chart.xy.model

import com.gitee.wsl.compose.chart.ChartAdapter
import com.gitee.wsl.compose.chart.ChartEntry

/**
 * Represents a point on a 2-d plot.
 * @param X The data type of the first dimension/axis
 * @param Y The data type of the second dimension/axis
 */
 interface PointEntry<X, Y>: ChartEntry {
    /**
     * The x-axis value of this Point.
     */
     val x: X

    /**
     * The y-axis value of this Point.
     */
     val y: Y
}

/**
 * Creates a new DefaultPoint at the specified coordinates.
 * @param X The type of the x-axis value
 * @param Y The type of the y-axis value
 */
@Suppress("FunctionNaming")
 fun <X, Y> PointEntry(x: X, y: Y): PointEntry<X, Y> = DefaultPointEntry(x, y)

/**
 * Default implementation of the Point interface.
 * @param X The type of the x-axis values
 * @param Y The type of the y-axis values
 */
 internal data class DefaultPointEntry<X, Y>(override val x: X, override val y: Y) : PointEntry<X, Y>


fun <X, Y> ChartAdapter.Companion.lines(builder: LinesBuilder<X, Y>.()->Unit):List<List<PointEntry<X,Y>>>{
    val lines = mutableListOf<List<PointEntry<X,Y>>>()
    object:LinesBuilder<X, Y>{
        override fun line(builder: LineBuilder<X, Y>.()->Unit) {
            val line = mutableListOf<PointEntry<X,Y>>()
            object:LineBuilder<X, Y>{
                override fun at(x: X, y: Y): Pair<X, Y> {
                    line.add(PointEntry(x,y))
                    return x to y
                }

                override fun Pair<X,Y>.lineTo(x:X, y:Y):Pair<X,Y> {
                    line.add(PointEntry(x,y))
                    return x to y
                }
            }
            lines.add(line)
        }
    }.builder()
    return lines
}

interface LinesBuilder<X, Y> {
    fun line(builder: LineBuilder<X, Y>.()->Unit)
}

interface LineBuilder<X, Y> {

    fun at(x:X, y:Y):Pair<X,Y>

    fun Pair<X,Y>.lineTo(x:X, y:Y):Pair<X,Y>
}